<?php

use Illuminate\Support\Facades\Log;

//解析框架异常错误-获取第一条
function getValidateMessage($message) {
    $messageArr = json_decode(json_encode($message), true);
    $msg = '';
    foreach ($messageArr as $val) {
        $msg = $val[0];
    }
    return $msg;
}

//索引转关联
function indexToAssoc($array, $key){
    return array_combine(array_column($array, $key), array_values($array));
}

function lockApi($lock_key, $expire_time = 1000, $lock_value = 1) {
    if (!app('redis')->setnx($lock_key, $lock_value)) {
        return false;
    }
    app('redis')->pexpire($lock_key, $expire_time);
    return true;
}
function unlockApi($lock_key) {
    app('redis')->del($lock_key);
}


//获得系统配置
function get_sys_config($key = '')
{
    $config = app('redis')->get('DB_CONFIG_DATA');

    $config_arr = json_decode($config,true);

    if(!empty($key)) {

        return isset($config_arr[$key]) ? $config_arr[$key] : '';
    }

    return $config_arr;
}

function isIos() {
    $client_type = app('request')->header('clientType');
    return strtolower($client_type) == 'ios';
}

function send_post_curl($url, $params, $headerParams = []) {

    $postdata = http_build_query($params);
    $length = strlen($postdata);
    $cl = curl_init($url);//①：初始化
    curl_setopt($cl, CURLOPT_POST, true);//②：设置属性
    curl_setopt($cl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    $header = ["Content-Type: application/x-www-form-urlencoded", "Content-length: " . $length];
    if(!empty($headerParams)){
        foreach ($headerParams as $v){
            array_push($header, $v);
        }
    }
//    curl_setopt($cl, CURLOPT_HTTPHEADER, ["Content-Type: application/x-www-form-urlencoded", "Content-length: " . $length]);
    curl_setopt($cl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($cl, CURLOPT_POSTFIELDS, $postdata);
    curl_setopt($cl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($cl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($cl, CURLOPT_SSL_VERIFYHOST, false);
    $content = curl_exec($cl);//③：执行并获取结果
    curl_close($cl);//④：释放句柄

    return $content;
}

/**
 * 手机格式验证
 * @param string $mobile 验证的手机号码
 * @return boolean
 * zhaojiping 修正
 */
function isMobile($mobile) {
    if (!empty($mobile)) {
        if (preg_match("/^1[3-9]\d{9}$/", $mobile)) {
            return true;
        }
    }

    return false;
}



/**
 * +----------------------------------------------------------
 * 生成随机字符串
 * +----------------------------------------------------------
 * @param int $length 要生成的随机字符串长度
 * @param string $type 随机码类型：0，数字+大小写字母；1，数字；2，小写字母；3，大写字母；4，特殊字符；-1，数字+大小写字母+特殊字符
 * +----------------------------------------------------------
 * @return string
 * +----------------------------------------------------------
 */
function randCode($length = 5, $type = 0) {
    $arr = [1 => "0123456789", 2 => "abcdefghijklmnopqrstuvwxyz", 3 => "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 4 => "~@#$%^&*(){}[]|"];
    if ($type == 0) {
        array_pop($arr);
        $string = implode("", $arr);
    } elseif ($type == "-1") {
        $string = implode("", $arr);
    } else {
        $string = $arr[$type];
    }
    $count = strlen($string) - 1;
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= $string[rand(0, $count)];
    }

    return $code;
}


function uniqidReal($lenght = 13) {
    // uniqid gives 13 chars, but you could adjust it to your needs.
    if (function_exists("random_bytes")) {
        $bytes = random_bytes(ceil($lenght / 2));
    } elseif (function_exists("openssl_random_pseudo_bytes")) {
        $bytes = openssl_random_pseudo_bytes(ceil($lenght / 2));
    } else {
        throw new Exception("no cryptographically secure random function available");
    }
    return substr(bin2hex($bytes), 0, $lenght);
}


/**
 * redis 集合 score 排行
 * @param int $value
 * @return float|int
 */
function getScoreByValue(int $value)
{
    $timestamp = 9999999999 - time();
    return $value * 10000000000 + $timestamp;
}

/**
 * 获取 redis 集合 score 对应的 value
 * @param string $score
 * @return bool|string
 */
function getValueByScore(string $score)
{
    $score = sprintf("%.0f", $score);
    return substr($score, 0, -10);
}

/**按时间设置zset的排序
 * @param $redis_key
 * @param $count
 * @param $member
 * @param $redis
 */
function zSetRedisScore($redis_key, $count, $member, $redis = null)
{
    if (empty($redis)) {
        $redis = app('redis');
    }
    $score = $redis->zscore($redis_key, $member) ?? '';
    if (empty($score)) {
        $oldCount = 0;
    } else {
        $oldCount = (int)getValueByScore($score);
    }
    $newScore = getScoreByValue($oldCount + $count);

    Log::error('zSetRedisScore:' . json_encode([$newScore, $score, $redis_key]));
    $redis->zincrby($redis_key, bcsub((string)$newScore, bcToInt($score)), $member);
}


function dateDiff($start_time, $end_time, $spr = '')
{
    $start_time = date_create($start_time);
    $end_time = date_create($end_time);
    $diff = date_diff($start_time, $end_time);
    if (!empty($spr)) {
        return $diff->$spr;
    }
    return $diff;
}

function getSign($param, $secret_1 = '', $secret_2 = '')
{
    $keysArr = array_keys($param);
    arsort($keysArr);
    $str = '';
    foreach($keysArr as $val)
    {
        if (is_array($param[$val])) {
            $str .= $val.json_encode($param[$val], JSON_UNESCAPED_UNICODE);
        } else {
            $str .= $val.$param[$val];
        }
    }
    if (empty($secret_1)) {
        $secret_1 = env('APP_SECRET_NEW');
    }
    if (empty($secret_2)) {
        $secret_2 = env('APP_SECRET');
    }
    $str = $secret_1.$str.$secret_2;
    return md5($str);
}

function containsChinese($str)
{
    return preg_match('/[\x{4e00}-\x{9fa5}]/u', $str);
}

//bcmatch高精度计算 处理数据
function bcToInt($number) {
    if (!preg_match('/^([+-]?\d+\.?\d*)[eE]([+-]?\d+)$/', $number, $matches)) {
        return $number;
    }

    $base = $matches[1];
    $exp = $matches[2];

    // 将基数转换为高精度字符串
    $base = rtrim($base, '.0'); // 清理末尾的零和点
    $scale = max(strlen(explode('.', $base)[1] ?? 0), 0); // 小数位数

    // 计算 10^exp
    $power = bcpow('10', $exp, $scale);

    // 基数 × 10^exp
    $result = bcmul($base, $power, 0); // 结果为整数

    return $result;
}


// 获取随机编码
function serialNumber($scene = 1)
{
    return time() . rand(10000, 99999) . $scene;
}

